package com.umakr.ax.app.web;


import com.umakr.ax.app.service.MsgWebService;
import com.umakr.ax.app.service.WechatAccountErrorLogWebService;
import com.umakr.ax.app.service.WechatOpenAccountWebService;
import com.umakr.ax.common.model.WechatAccount;
import com.umakr.ax.common.model.WechatOpenAccount;
import com.umakr.ax.common.service.WechatAccountService;
import com.umakr.ax.common.service.WechatOpenAccountService;
import com.umakr.ax.core.base.AbstractController;
import com.umakr.ax.oss.service.StsServiceSample;
import com.umakr.ax.utils.AudioUtil;
import com.umakr.ax.utils.DateUtil;
import com.umakr.ax.wechat.util.*;
import com.umakr.ax.xf.Mp3ConvertorAndXfTransformService;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jeewx.api.core.exception.WexinReqException;
import org.jeewx.api.mp.aes.AesException;
import org.jeewx.api.mp.aes.WXBizMsgCrypt;
import org.jeewx.api.third.JwThirdAPI;
import org.jeewx.api.third.model.*;
import org.jeewx.api.wxbase.wxmedia.JwMediaAPI;
import org.jeewx.api.wxbase.wxmedia.model.WxDwonload;
import org.jeewx.api.wxuser.user.JwUserAPI;
import org.jeewx.api.wxuser.user.model.Wxuser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

/**
 * 微信公众号第三方平台全网发布
 *
 * @author Wmdz
 * @since 2018-01-03
 */
@Controller
@RequestMapping("/api/web/wechat/wechatopen")
public class WechatOpenWebController extends AbstractController {

    @Autowired
    Environment env;

    @Autowired
    StsServiceSample stsServiceSample;

    @Autowired
    WechatOpenAccountService wechatOpenAccountService;
    @Autowired
    WechatOpenAccountWebService wechatOpenAccountWebService;
    @Autowired
    WechatAccountService wechatAccountService;
    @Autowired
    MsgWebService msgWebService;

    @Autowired
    WechatAccountErrorLogWebService wechatAccountErrorLogWebService;

    @Autowired
    Mp3ConvertorAndXfTransformService mp3ConvertorAndXfTransformService;

    @Value("${native.resource.path}")
    public String localUrl;

    private static String ERRORCODE_EQUAL_STRING = "errcode=";
    private static String EVENT_STRING = "event";
    private static String TEXT_STRING = "text";
    private static String IMAGE_STRING = "image";
    private static String LOCATION_STRING = "location";
    private static String VOICE_STRING = "voice";
    private static String TESTCOMPONENT_MSG_TYPE_TEXT_STRING = "TESTCOMPONENT_MSG_TYPE_TEXT";
    private static String QUERY_AUTH_CODE_STRING = "QUERY_AUTH_CODE";

    /**
     * 一键授权功能
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws AesException
     * @throws DocumentException
     */
    @RequestMapping(value = "/goAuthor/{rsId}")
    public void goAuthor(HttpServletRequest request, HttpServletResponse response, @PathVariable Long rsId) throws IOException, AesException, DocumentException {
        try {
            WechatOpenAccount wechatOpenAccount = wechatOpenAccountService.load();
            String componentAccesstoken = wechatOpenAccountWebService.getComponentAccesstoken(wechatOpenAccount);
            //预授权码
            String preAuthCode = JwThirdAPI.getPreAuthCode(wechatOpenAccount.getAppid(), componentAccesstoken);
            String wechatOpenDomain = env.getProperty("wechat.open.domain");
            String url = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=" + wechatOpenAccount.getAppid() + "&pre_auth_code=" + preAuthCode + "&auth_type=" + wechatOpenAccount.getAuthType() + "&redirect_uri=" + wechatOpenDomain + "/api/web/wechat/wechatopen/authorCallback/" + rsId;
            logger.info(url);
            response.sendRedirect(url);
        } catch (WexinReqException e) {
            e.printStackTrace();
        }

    }

    /**
     * 授权后回调
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws AesException
     * @throws DocumentException
     */
    @RequestMapping(value = "/authorCallback/{rsId}")
    public void authorCallback(HttpServletRequest request, HttpServletResponse response, @PathVariable Long rsId) throws IOException, AesException, DocumentException, WexinReqException {
        String authCode = request.getParameter("auth_code");
        String expiresIn = request.getParameter("expires_in");
        logger.info("auth_code : " + authCode);
        logger.info("expires_in : " + expiresIn);

      /*  //TODO 授权成功
        output(response, "Auth Success !"); // 输出响应的内容。*/


        //auth_code : queryauthcode@@@O1jY7Ays6Ob2AFPRb8EJQ2aiYcVUffNNVTjSxWmiKyoPVTqOurnrVMP_PO6w47gx6K5dE7cH2USsuFsZZQXc-Q expires_in : 3600
        //绑定电台信息和公众号信息 appid 原始id
        WechatOpenAccount wechatOpenAccount = wechatOpenAccountService.load();
        String componentAccesstoken = wechatOpenAccountWebService.getComponentAccesstoken(wechatOpenAccount);
        logger.info("获取component_access_token = " + componentAccesstoken);


        JSONObject apiQueryAuthInfo = JwThirdAPI.getApiQueryAuthInfo(wechatOpenAccount.getAppid(), authCode, componentAccesstoken);
        logger.info("apiQueryAuthInfo = " + apiQueryAuthInfo);

        JSONObject authorizationInfo = apiQueryAuthInfo.getJSONObject("authorization_info");
        String authorizerAppid = authorizationInfo.getString("authorizer_appid");
        String authorizerAccessToken = authorizationInfo.getString("authorizer_access_token");
        String authorizerExpiresIn = authorizationInfo.getString("expires_in");
        String authorizerRefreshToken = authorizationInfo.getString("authorizer_refresh_token");
        logger.info("获取authorizer_appid = " + authorizerAppid);
        logger.info("获取authorizer_access_token = " + authorizerAccessToken);
        logger.info("获取authorizer_expires_in = " + authorizerExpiresIn);
        logger.info("获取authorizer_refresh_token = " + authorizerRefreshToken);

        ApiGetAuthorizer apiGetAuthorizer = new ApiGetAuthorizer();
        apiGetAuthorizer.setAuthorizer_appid(authorizerAppid);
        apiGetAuthorizer.setComponent_appid(wechatOpenAccount.getAppid());
        ApiGetAuthorizerRet apiGetAuthorizerRet = JwThirdAPI.apiGetAuthorizerInfo(apiGetAuthorizer, componentAccesstoken);
        logger.info("获取apiGetAuthorizerRet = " + apiGetAuthorizerRet);
        ApiGetAuthorizerRetAuthorizer apiGetAuthorizerRetAuthorizer = apiGetAuthorizerRet.getAuthorizer_info();
        String userName = apiGetAuthorizerRetAuthorizer.getUser_name();
        String nickName = apiGetAuthorizerRetAuthorizer.getNick_name();
        String headImg = apiGetAuthorizerRetAuthorizer.getHead_img();
        String alias = apiGetAuthorizerRetAuthorizer.getAlias();
        ApiGetAuthorizerRetAuthorizerSType serviceTypeInfo = apiGetAuthorizerRetAuthorizer.getService_type_info();
        ApiGetAuthorizerRetAuthorizerVType verifyTypeInfo = apiGetAuthorizerRetAuthorizer.getVerify_type_info();

        logger.info("获取user_name = " + userName);

        wechatOpenAccount.setAuthCode(authCode);
        wechatOpenAccountService.save(wechatOpenAccount);

        WechatAccount wechatAccount = wechatAccountService.loadByAppid(authorizerAppid);
        if (wechatAccount == null) {
            wechatAccount = new WechatAccount();
        }
        wechatAccount.setAccountAppid(authorizerAppid);
        wechatAccount.setAccountAccesstoken(authorizerAccessToken);
        wechatAccount.setAccountRefreshtoken(authorizerRefreshToken);
        wechatAccount.setAccesstokenExpiresIn(Integer.parseInt(authorizerExpiresIn));
        wechatAccount.setAccountName(nickName);
        wechatAccount.setAccountHeadImg(headImg);
        wechatAccount.setAccountNumber(alias);
        wechatAccount.setAccountServiceTypeInfo(serviceTypeInfo.getId());
        wechatAccount.setAccountVerifyTypeInfo(verifyTypeInfo.getId());
        wechatAccount.setAccountOriginalid(userName);
        wechatAccount.setRsId(rsId);
        wechatAccountService.insertOrUpdate(wechatAccount);

        //更新电台字段
        String wechatOpenDomain = env.getProperty("wechat.open.domain");
        response.sendRedirect(wechatOpenDomain + "?rsId="+rsId+"/#/radioStation/WeiXinSuccess");
    }


    /*@RequestMapping(value = "/tangtengfeiCallback")
    public void tangtengfeiCallback(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Long rsId = 1L;
        //更新电台字段
        String domain = "http://localhost:8000/";
        response.sendRedirect(domain + "?rsId=1#/radioStation/WeiXinSuccess");
    }
*/    /**
     * 授权事件接收
     * 第一步
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws AesException
     * @throws DocumentException
     */
    @RequestMapping(value = "/event/authorize")
    public void acceptAuthorizeEvent(HttpServletRequest request, HttpServletResponse response) throws IOException, AesException, DocumentException, WexinReqException {
        logger.info("微信第三方平台---------微信推送Ticket消息10分钟一次---------" + DateUtil.getDateTime());
        //微信第三方平台---------微信推送Ticket消息10分钟一次---------2018-01-06 12:26:29
        //微信第三方平台---------微信推送Ticket消息10分钟一次---------2018-01-06 11:56:07

        processAuthorizeEvent(request);

        //2个小时内要重新获取
        refreshAccessToken();
        // 输出响应的内容。
        output(response, "success");
    }

    /**
     * 处理授权事件的推送
     *
     * @param request
     * @throws IOException
     * @throws AesException
     * @throws DocumentException
     */
    public WechatOpenAccount processAuthorizeEvent(HttpServletRequest request) {

        WechatOpenAccount wechatOpenAccount = null;
        WechatAccount wechatAccount = null;

        try {
            wechatOpenAccount = wechatOpenAccountService.load();

            String nonce = request.getParameter("nonce");
            String timestamp = request.getParameter("timestamp");
            String signature = request.getParameter("signature");
            String msgSignature = request.getParameter("msg_signature");

            if (!StringUtils.isNotBlank(msgSignature)) {
                return null;
            }

            //true
            boolean isValid = checkSignature(wechatOpenAccount.getToken(), signature, timestamp, nonce);
            if (isValid) {
                StringBuilder sb = new StringBuilder();
                BufferedReader in = request.getReader();
                String line;
                while ((line = in.readLine()) != null) {
                    sb.append(line);
                }
                String xml = sb.toString();
                logger.info("第三方平台全网发布---------原始 Xml=" + xml);
                /**<xml>
                 <AppId><![CDATA[wxc92172aa9f766406]]></AppId>
                 <Encrypt><![CDATA[Pv2cSqldSQTISd34DsLGnGhklzvPRdrfm7lr30IxIEVizNrK1PXellE03PbuCas/Mo0k6e7f6RLJWD7hnYEcVLRMj1mplzlP2vDW/wwgB++p7BLesMcKv2ZZ/spKVALy5GJ6tQN5xqmeWMWQCTgOusELHBGcImIlZqlQkBZ79UqxGIMIeVlMIFvfalTb+ywK63e+lHbIV7oOS5WFKpsEEeShrmQjQK7JtAl51giEw4RF2vwgs5lg42DtojG2hnOtNv29aq8EXiDVb7e1mXtLwd8DD44pJ5ewpY4jf4REkArW/iqwr3isdJIDsVQbNyH9sJKU9V27r+cNzSCDpTEsa4OckQ4dLW9D36zDH0hhHTVtREIQCSMX9h7bwFNfWHFLzZ7WB38+6WGhplhB7gSrcSKGwI5F+dbUsoVRfjSqSK11eqxgQuJyrKQzUGq5b+dxqxNY/zBaxWIGv3VuAiOlkfmbQVrbnUBBTVROtdWy1c639uuJxaUfwEnzpxPOaeiYNRhvuSYw5omGUmL1IUKpkmk4ST+h9pO58M61raDYkzKuueB4QWjD4Bjq3AIyznyOZBA0vPj7YrFrMbRxtt+ESsi2qrj2Hg8VsmGCBocpTAhtXsFw+IrK1qN3qpd75Chqb7lLpSVGVJCZhT/3hvLhmkWXK5k43y4p+aM4W7xRY3ZCBIWqgTVFpfKz+IhN13tUd7lU/v7CtPm+Nvp0ZpUecV7XMC/QAZrzYqBkiGv0rmgSL1XXbCMUMaUFd/C2dEq7xHScm8yA8Y2vp3d15olrjgMbb/FnQNtaYPw46yHX2Mc=]]></Encrypt>
                 </xml>*/
                /**<xml>
                 <AppId><![CDATA[wxc92172aa9f766406]]></AppId>
                 <Encrypt><![CDATA[zhzV3pQ3MBYd5UoD6aO1A0u8tWvjTknDTBrAIMZqwyTc2mYAn4qlggu/Q3/ekf0kG80q8oYrTgBdt+kI5EsQFhER0FcJXLF/g/RDFs4vFuPnkVB90uSBgs1RBYdPS0IDsHKzucgvx8yOjw1Ah17X1AnYPJCLrjhYNFCL2yNOsd1cxwP6Kxlisg/gWy0J0Maah4e/Hml0UVbezgF2KjYn3woH3Gzt2B+GWkX8jqTd591Zb1HZenEGmu24xEaKCWa2KjUtVixMAw0j98ZM3qDZqxkY+vFppZ+mcywsIaYIFE9rpGGQcu74+I9HLoXwXF1bUqAOtEetueYvWV/jS0huPg==]]></Encrypt>
                 </xml>*/
                // 第三方平台组件加密密钥
                String encodingAesKey = wechatOpenAccount.getEncodingAesKey();
                WXBizMsgCrypt pc = new WXBizMsgCrypt(wechatOpenAccount.getToken(), encodingAesKey, wechatOpenAccount.getAppid());
                xml = pc.decryptMsg(msgSignature, timestamp, nonce, xml);
                logger.info("第三方平台全网发布---------解密后 Xml=" + xml);
                /**授权？
                 <xml><AppId><![CDATA[wxc92172aa9f766406]]></AppId>
                 <CreateTime>1515212788</CreateTime>
                 <InfoType><![CDATA[authorized]]></InfoType>
                 <AuthorizerAppid><![CDATA[wx570bc396a51b8ff8]]></AuthorizerAppid>
                 <AuthorizationCode><![CDATA[queryauthcode@@@FRAb2PoTqAqmpm9qU8Z_CgLHhududFLz-soKXGCH1Rte8S3cg1q9lNI8iAuBmJk5enkwz3UflaWpeNexYxpv6w]]></AuthorizationCode>
                 <AuthorizationCodeExpiredTime><![CDATA[1515216388]]></AuthorizationCodeExpiredTime>
                 <PreAuthCode><![CDATA[preauthcode@@@5qNY23s4lLrOG_Y79foTralAlprBFk9NTZn1MXxmlx8RMm-pReELEszb8Jmcb_Zy]]></PreAuthCode>
                 </xml>
                 */
                /**取消授权？<xml><AppId><![CDATA[wxc92172aa9f766406]]></AppId>
                 <CreateTime>1515210966</CreateTime>
                 <InfoType><![CDATA[unauthorized]]></InfoType>
                 <AuthorizerAppid><![CDATA[wx570bc396a51b8ff8]]></AuthorizerAppid>
                 </xml>*/
                /**十分钟
                 <xml><AppId><![CDATA[wxc92172aa9f766406]]></AppId>
                 <CreateTime>1515231578</CreateTime>
                 <InfoType><![CDATA[component_verify_ticket]]></InfoType>
                 <ComponentVerifyTicket><![CDATA[ticket@@@9XW2Woloqlgj1w5MODv1hmVjGsYQZ-cWznUV0JJhffSnXiJN_GwUUaTB23R2yysEscPTzppCMxLRFf9nhlUTaw]]></ComponentVerifyTicket>
                 </xml>
                 */
                wechatOpenAccount = processAuthorizationEvent(xml, wechatOpenAccount);
                // 此时加密的xml数据中ToUserName是非加密的，解析xml获取即可 现在是AppId
                String appId = getParamFromXml(xml, "AppId");
                /**
                 * 开放平台appid
                 * 第三方平台全网发布---------appid---------getAuthorizerAppidFromXml(xml)---------appId=wxc92172aa9f766406
                 * 第三方平台全网发布---------appid---------getAuthorizerAppidFromXml(xml)---------appId=null
                  */
                logger.info("第三方平台全网发布---------appid---------getAuthorizerAppidFromXml(xml)---------appId=" + appId);

            }
            return wechatOpenAccount;

        } catch (Exception e) {
            logger.info("服务器公网IP: " + IpUtil.getV4IP());

            Map<String, Object> data = new HashMap<>();
            data.put("errorInfo", ExceptionUtil.getExceptionDetail(e));
            String errorCode = "";
            //获取第三方平台access_token！errcode=61004,errmsg = access clientip is not registered hint: [dyq8ja02921501] requestIP: 49.118.255.20
            if (e.getMessage().indexOf(ERRORCODE_EQUAL_STRING) != -1) {
                errorCode = e.getMessage().substring(e.getMessage().indexOf("errcode=") + "errcode=".length(), e.getMessage().indexOf(","));
            }
            data.put("errorCode", errorCode);
            data.put("errorDesc", e.getMessage());
            Map result = wechatAccountErrorLogWebService.save(data);
            return wechatOpenAccount;
        }
    }


    /**
     * 刷新ACCESS_TOKEN 2个小时内要重新获取
     *
     * @throws WexinReqException
     */
    @RequestMapping(value = "/refreshAccessToken")
    public void refreshAccessToken() {
        WechatOpenAccount wechatOpenAccount = null;
        WechatAccount currentWechatAccount = null;
        try {
            wechatOpenAccount = wechatOpenAccountService.load();
            String componentAccesstoken = wechatOpenAccountWebService.getComponentAccesstoken(wechatOpenAccount);

            List<WechatAccount> wechatAccountList = wechatAccountService.queryList(new HashMap<>());
            for (WechatAccount wechatAccount : wechatAccountList) {
                currentWechatAccount = wechatAccount;

                //过期重新获取
                ApiAuthorizerToken apiAuthorizerToken = new ApiAuthorizerToken();
                apiAuthorizerToken.setAuthorizer_appid(wechatAccount.getAccountAppid());
                apiAuthorizerToken.setAuthorizer_refresh_token(wechatAccount.getAccountRefreshtoken());
                apiAuthorizerToken.setComponent_appid(wechatOpenAccount.getAppid());
                ApiAuthorizerTokenRet apiAuthorizerTokenRet = JwThirdApix.apiAuthorizerToken(apiAuthorizerToken, componentAccesstoken);

                String authorizerRefreshToken = apiAuthorizerTokenRet.getAuthorizer_refresh_token();
                String authorizerAccessToken = apiAuthorizerTokenRet.getAuthorizer_access_token();
                Integer authorizerExpiresIn = apiAuthorizerTokenRet.getExpires_in();


                wechatAccount.setAccountAccesstoken(authorizerAccessToken);
                wechatAccount.setAccountRefreshtoken(authorizerRefreshToken);
                wechatAccount.setAccesstokenExpiresIn(authorizerExpiresIn);
                wechatAccountService.insertOrUpdate(wechatAccount);

                logger.info("微信第三方平台---------2个小时内要重新获取---------appid=" + wechatAccount.getAccountAppid() + " authorizer_access_token=" + authorizerAccessToken);
                logger.info("微信第三方平台---------2个小时内要重新获取---------appid=" + wechatAccount.getAccountAppid() + " authorizer_refresh_token=" + authorizerRefreshToken);
            }
        } catch (Exception e) {
            logger.info("服务器公网IP: " + IpUtil.getV4IP());

            Map<String, Object> data = new HashMap<>();
            data.put("errorInfo", ExceptionUtil.getExceptionDetail(e));
            String errorCode = "";
            //获取第三方平台access_token！errcode=61004,errmsg = access clientip is not registered hint: [dyq8ja02921501] requestIP: 49.118.255.20
            if (e != null && e.getMessage() != null && e.getMessage().indexOf(ERRORCODE_EQUAL_STRING) != -1) {
                errorCode = e.getMessage().substring(e.getMessage().indexOf("errcode=") + "errcode=".length(), e.getMessage().indexOf(","));
            }
            data.put("errorCode", errorCode);
            data.put("errorDesc", e.getMessage());
            data.put("waId", (currentWechatAccount != null) ? currentWechatAccount.getId() : null);
            data.put("rsId", (currentWechatAccount != null) ? currentWechatAccount.getRsId() : null);
            Map result = wechatAccountErrorLogWebService.save(data);
        }
    }

    /**
     * 判断是否加密
     *
     * @param token
     * @param signature
     * @param timestamp
     * @param nonce
     * @return
     */
    public static boolean checkSignature(String token, String signature, String timestamp, String nonce) {

        System.out.println("###token:" + token + ";signature:" + signature + ";timestamp:" + timestamp + "nonce:" + nonce);
        //###token:umk1234567890123456789012345678901234567890;signature:961b3641132360ecb334d049e62b7a4310398b9e;timestamp:1515212788nonce:55386538
        //###token:umk1234567890123456789012345678901234567890;signature:bafdd30c1354cc49f4375e95e6cb1713def6ea68;timestamp:1515210966nonce:1562891409

        boolean flag = false;
        if (signature != null && !"".equals(signature) && timestamp != null && !"".equals(timestamp) && nonce != null && !"".equals(nonce)) {
            String sha1 = "";
            String[] ss = new String[]{token, timestamp, nonce};
            Arrays.sort(ss);
            for (String s : ss) {
                sha1 += s;
            }

            sha1 = AddSha1.sha1(sha1);

            if (sha1.equals(signature)) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 获取xml中的参数
     *
     * @param xml
     * @return
     */
    private String getParamFromXml(String xml, String param) {
        try {
            Document doc = DocumentHelper.parseText(xml);
            Element rootElt = doc.getRootElement();
            String value = rootElt.elementText(param);
            return value;
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 保存Ticket
     *
     * @param xml
     */
    private WechatOpenAccount processAuthorizationEvent(String xml, WechatOpenAccount wechatOpenAccount) {
        try {
            Document doc = DocumentHelper.parseText(xml);
            Element rootElt = doc.getRootElement();
            String ticket = rootElt.elementText("ComponentVerifyTicket");
            //开放平台id
            String appid = rootElt.elementText("AppId");
            if (OconvertUtils.isNotEmpty(ticket)) {
                logger.info("8、推送component_verify_ticket协议---------ticket = " + ticket);
                wechatOpenAccount.setTicket(ticket);
                wechatOpenAccount.setAddTicketTime(SpeedStorage.getSystemDate());
                wechatOpenAccount.setAppid(appid);
                wechatOpenAccountService.save(wechatOpenAccount);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return wechatOpenAccount;
    }

    /**
     * 接收普通文本消息
     * 第二步
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws AesException
     * @throws DocumentException
     */
    @RequestMapping(value = "{appid}/callback")
    public void acceptMessageAndEvent(HttpServletRequest request, HttpServletResponse response, @PathVariable String appid) throws IOException, AesException, DocumentException, WexinReqException {
        String msgSignature = request.getParameter("msg_signature");
        logger.info("第三方平台全网发布---------{appid}/callback---------验证开始。。。。appid = " + appid + " , msg_signature=" + msgSignature);
        //第三方平台全网发布---------{appid}/callback---------验证开始。。。。msg_signature=0c31fbbb50a135c1cc694cefc7ce800261c691f8
        //第三方平台全网发布---------{appid}/callback---------验证开始。。。。msg_signature=9f7d662d6bafb9aee211917a6cc89a05ea3af023
        //第三方平台全网发布---------{appid}/callback---------验证开始。。。。msg_signature=1ee10c15b19265d70d09780e0219251f9ab5211b

        if (!StringUtils.isNotBlank(msgSignature)) {
            return;// 微信推送给第三方开放平台的消息一定是加过密的，无消息加密无法解密消息
        }

        StringBuilder sb = new StringBuilder();
        BufferedReader in = request.getReader();
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();

        String xml = sb.toString();
        Document doc = DocumentHelper.parseText(xml);
        Element rootElt = doc.getRootElement();
        String toUserName = rootElt.elementText("ToUserName");

        logger.info("xml=" + xml);
        //微信全网测试账号
        logger.info("全网发布接入检测消息反馈开始---------appid=" + appid + "---------toUserName=" + toUserName);
        //全网发布接入检测消息反馈开始---------APPID=---------toUserName=gh_3c884a361561
        //全网发布接入检测消息反馈开始---------APPID=---------toUserName=gh_3c884a361561
        //全网发布接入检测消息反馈开始---------APPID=---------toUserName=gh_3c884a361561
        checkWechatAllNetworkCheck(request, response, xml);
    }

    public void checkWechatAllNetworkCheck(HttpServletRequest request, HttpServletResponse response, String xml) throws DocumentException, IOException, AesException, WexinReqException {
        String nonce = request.getParameter("nonce");
        String timestamp = request.getParameter("timestamp");
        String msgSignature = request.getParameter("msg_signature");

        WechatOpenAccount wechatOpenAccount = wechatOpenAccountService.load();

        WXBizMsgCrypt pc = new WXBizMsgCrypt(wechatOpenAccount.getToken(), wechatOpenAccount.getEncodingAesKey(), wechatOpenAccount.getAppid());
        xml = pc.decryptMsg(msgSignature, timestamp, nonce, xml);

        Document doc = DocumentHelper.parseText(xml);
        Element rootElt = doc.getRootElement();
        String msgType = rootElt.elementText("MsgType");
        String toUserName = rootElt.elementText("ToUserName");
        String fromUserName = rootElt.elementText("FromUserName");

        logger.info("---全网发布接入检测--step.1---------msgType=" + msgType + "---------toUserName=" + toUserName + "---------fromUserName=" + fromUserName);
        //---全网发布接入检测--step.1---------msgType=text---------toUserName=gh_3c884a361561---------fromUserName=ozy4qt5QUADNXORxCVipKMV9dss0
        //---全网发布接入检测--step.1---------msgType=text---------toUserName=gh_3c884a361561---------fromUserName=ozy4qt5QUADNXORxCVipKMV9dss0
        //---全网发布接入检测--step.1---------msgType=event---------toUserName=gh_3c884a361561---------fromUserName=ozy4qt5QUADNXORxCVipKMV9dss0
        logger.info("---全网发布接入检测--step.2---------xml=" + xml);
        //---全网发布接入检测--step.2---------xml=
        /**<xml><ToUserName><![CDATA[gh_3c884a361561]]></ToUserName>
         <FromUserName><![CDATA[ozy4qt5QUADNXORxCVipKMV9dss0]]></FromUserName>
         <CreateTime>1515210940</CreateTime>
         <MsgType><![CDATA[text]]></MsgType>
         <Content><![CDATA[QUERY_AUTH_CODE:queryauthcode@@@pyO9K-FF4VjKKeBmCIfofkcWxJ10tSlydAM6D4VTm-KdTg2lzHw7I24U2figvamgRX2rM784XsyspmRfp5HP8Q]]></Content>
         <MsgId>6507781434248417810</MsgId>
         </xml>*/
        /**<xml><ToUserName><![CDATA[gh_3c884a361561]]></ToUserName>
         <FromUserName><![CDATA[ozy4qt5QUADNXORxCVipKMV9dss0]]></FromUserName>
         <CreateTime>1515210950</CreateTime>
         <MsgType><![CDATA[text]]></MsgType>
         <Content><![CDATA[TESTCOMPONENT_MSG_TYPE_TEXT]]></Content>
         <MsgId>6507781477198090771</MsgId>
         </xml>*/
        /**<xml><ToUserName><![CDATA[gh_3c884a361561]]></ToUserName>
         <FromUserName><![CDATA[ozy4qt5QUADNXORxCVipKMV9dss0]]></FromUserName>
         <CreateTime>1515210959</CreateTime>
         <MsgType><![CDATA[event]]></MsgType>
         <Event><![CDATA[LOCATION]]></Event>
         <Latitude>111.000000</Latitude>
         <Longitude>222.000000</Longitude>
         <Precision>333.000000</Precision>
         </xml>*/

        WechatAccount wechatAccount = wechatAccountService.loadByOriginalid(toUserName);

        if (EVENT_STRING.equals(msgType)) {
            logger.info("---全网发布接入检测--step.3---------事件消息--------");
            //第三次
            //---全网发布接入检测--step.3---------事件消息--------

            String event = rootElt.elementText("Event");
            replyEventMessage(request, response, event, toUserName, fromUserName);
        } else if (TEXT_STRING.equals(msgType)) {
            logger.info("---全网发布接入检测--step.3---------文本消息--------");
            //第一次 第二次
            // --全网发布接入检测--step.3---------文本消息--------
            // ---全网发布接入检测--step.3---------文本消息--------

            String content = rootElt.elementText("Content");
            processTextMessage(request, response, content, toUserName, fromUserName);

            //文本消息处理存入数据库
            /**<xml><ToUserName><![CDATA[gh_0dedd6e60555]]></ToUserName>
             <FromUserName><![CDATA[oEl-4uETCGjpmbYPmL1vwG7JOW4Q]]></FromUserName>
             <CreateTime>1515226271</CreateTime>
             <MsgType><![CDATA[text]]></MsgType>
             <Content><![CDATA[测试开放平台文字]]></Content>
             <MsgId>6507847280413347084</MsgId>
             </xml>*/
            Map<String, String> wechatMsgData = new HashMap<>();
            wechatMsgData.put("ToUserName", rootElt.elementText("ToUserName"));
            wechatMsgData.put("FromUserName", rootElt.elementText("FromUserName"));
            wechatMsgData.put("CreateTime", rootElt.elementText("CreateTime"));
            wechatMsgData.put("MsgType", rootElt.elementText("MsgType"));
            wechatMsgData.put("Content", rootElt.elementText("Content"));
            wechatMsgData.put("MsgId", rootElt.elementText("MsgId"));

            String msgAttachmentAddr = wechatMsgData.get("Content");
            String msgTxtContent = "";
            Date msgTime = new Date(Long.parseLong(wechatMsgData.get("CreateTime")) * 1000);
            //0、text 1、语音 2、图片 3、位置
            Integer msgContentType = 0;
            //语音长度
            Integer radioLen = 0;
            String positionCoor = "";
            String positionName = "";
            //电台id 这里需要绑定公众号appid或者公众号原始id与电台id绑定
            Long rsId = wechatAccount.getRsId();
            saveMsg(wechatMsgData.get("ToUserName"), wechatMsgData.get("FromUserName"), wechatAccount, msgAttachmentAddr, msgTxtContent, msgTime, msgContentType, radioLen, positionCoor, positionName, rsId, wechatMsgData);

        } else if (IMAGE_STRING.equals(msgType)) {
            /**<xml><ToUserName><![CDATA[gh_0dedd6e60555]]></ToUserName>
             <FromUserName><![CDATA[oEl-4uETCGjpmbYPmL1vwG7JOW4Q]]></FromUserName>
             <CreateTime>1515226283</CreateTime>
             <MsgType><![CDATA[image]]></MsgType>
             <PicUrl><![CDATA[http://mmbiz.qpic.cn/mmbiz_jpg/ibQHT1qeJjncwnhKSZ1Gyib4g9MjAFD9ibJOxhyf9y2JxfQyZHjXaCOj2Ioue9tEByD0PKXABVSeZo0licial0qIsibA/0]]></PicUrl>
             <MsgId>6507847331952954638</MsgId>
             <MediaId><![CDATA[7qvWGrugizJCCkrwVlAEYvum5FefaIwqAO3rqmrGt3mdHA548M9yZ7kBNbnrtmnx]]></MediaId>
             </xml>*/
            Map<String, String> wechatMsgData = new HashMap<>();
            wechatMsgData.put("ToUserName", rootElt.elementText("ToUserName"));
            wechatMsgData.put("FromUserName", rootElt.elementText("FromUserName"));
            wechatMsgData.put("CreateTime", rootElt.elementText("CreateTime"));
            wechatMsgData.put("MsgType", rootElt.elementText("MsgType"));
            wechatMsgData.put("PicUrl", rootElt.elementText("PicUrl"));
            wechatMsgData.put("MsgId", rootElt.elementText("MsgId"));
            wechatMsgData.put("MediaId", rootElt.elementText("MediaId"));

            String msgAttachmentAddr = wechatMsgData.get("PicUrl");
            String msgTxtContent = "";
            Date msgTime = new Date(Long.parseLong(wechatMsgData.get("CreateTime")) * 1000);
            //0、text 1、语音 2、图片 3、位置
            Integer msgContentType = 2;
            //语音长度
            Integer radioLen = 0;
            String positionCoor = "";
            String positionName = "";
            //电台id 这里需要绑定公众号appid或者公众号原始id与电台id绑定
            Long rsId = wechatAccount.getRsId();


            //预创建目录
            String filePath = env.getProperty("media.dir") + "/image/" + wechatAccount.getRsId() + "/" + wechatAccount.getAccountOriginalid();
            File dir = new File(filePath);
            if(!dir.exists() && !dir.isDirectory()){
                dir .mkdirs();
            }

            //下载
            String ACCESS_TOKEN = wechatAccount.getAccountAccesstoken();
            WxDwonload voiceFile = JwMediaAPI.downMedia(ACCESS_TOKEN, wechatMsgData.get("MediaId"), filePath);
            String newFilename = voiceFile.getFileName() + ((wechatMsgData.get("Format") != null) ? wechatMsgData.get("Format") : "");
            FileToolkit.renameFile(voiceFile.getFilepath() + "/" + voiceFile.getFileName(), newFilename);
            String localFilePath = voiceFile.getFilepath() + "/" + newFilename;
            //微信用户id都定为-1
            Long userId = -1L;
            String ossFilePath = env.getProperty("wechat.image.osspath");
            Map<String,Object> result = (Map<String, Object>) stsServiceSample.fileUpload(userId, new File(localFilePath), ossFilePath);
            //阿里云相对路径
            msgAttachmentAddr = ((Map<String,String>)(result.get("data"))).get("upUrl").toString();

            saveMsg(wechatMsgData.get("ToUserName"), wechatMsgData.get("FromUserName"), wechatAccount, msgAttachmentAddr, msgTxtContent, msgTime, msgContentType, radioLen, positionCoor, positionName, rsId, wechatMsgData);
        } else if (LOCATION_STRING.equals(msgType)) {
            /**<xml><ToUserName><![CDATA[gh_0dedd6e60555]]></ToUserName>
             <FromUserName><![CDATA[oEl-4uETCGjpmbYPmL1vwG7JOW4Q]]></FromUserName>
             <CreateTime>1515226314</CreateTime>
             <MsgType><![CDATA[location]]></MsgType>
             <Location_X>43.846607</Location_X>
             <Location_Y>87.483608</Location_Y>
             <Scale>15</Scale>
             <Label><![CDATA[乌鲁木齐市新疆软件园(乌市喀纳斯湖北路455号)]]></Label>
             <MsgId>6507847465096940822</MsgId>
             </xml>
             */
            Map<String, String> wechatMsgData = new HashMap<>();
            wechatMsgData.put("ToUserName", rootElt.elementText("ToUserName"));
            wechatMsgData.put("FromUserName", rootElt.elementText("FromUserName"));
            wechatMsgData.put("CreateTime", rootElt.elementText("CreateTime"));
            wechatMsgData.put("MsgType", rootElt.elementText("MsgType"));
            wechatMsgData.put("Location_X", rootElt.elementText("Location_X"));
            wechatMsgData.put("Location_Y", rootElt.elementText("Location_Y"));
            wechatMsgData.put("Scale", rootElt.elementText("Scale"));
            wechatMsgData.put("Label", rootElt.elementText("Label"));
            wechatMsgData.put("MsgId", rootElt.elementText("MsgId"));

            String msgAttachmentAddr = "";
            String msgTxtContent = "";
            Date msgTime = new Date(Long.parseLong(wechatMsgData.get("CreateTime")) * 1000);
            //0、text 1、语音 2、图片 3、位置
            Integer msgContentType = 3;
            //语音长度
            Integer radioLen = 0;
            String positionCoor = wechatMsgData.get("Location_X") + "," + wechatMsgData.get("Location_Y");
            String positionName = wechatMsgData.get("Label");
            //电台id 这里需要绑定公众号appid或者公众号原始id与电台id绑定
            Long rsId = wechatAccount.getRsId();

            saveMsg(wechatMsgData.get("ToUserName"), wechatMsgData.get("FromUserName"), wechatAccount, msgAttachmentAddr, msgTxtContent, msgTime, msgContentType, radioLen, positionCoor, positionName, rsId, wechatMsgData);
        } else if (VOICE_STRING.equals(msgType)) {
            /**<xml><ToUserName><![CDATA[gh_0dedd6e60555]]></ToUserName>
             <FromUserName><![CDATA[oEl-4uETCGjpmbYPmL1vwG7JOW4Q]]></FromUserName>
             <CreateTime>1515226440</CreateTime>
             <MsgType><![CDATA[voice]]></MsgType>
             <MediaId><![CDATA[U6x6vej7BbNxNFzjvlGOk3mQ8pqgcdr2h4lUIkjgltpTNbxH7-IfDxyGbyF4fXL0]]></MediaId>
             <Format><![CDATA[amr]]></Format>
             <MsgId>6507848005834506240</MsgId>
             <Recognition><![CDATA[我啊！]]></Recognition>
             </xml>
             */
            Map<String, String> wechatMsgData = new HashMap<>();
            wechatMsgData.put("ToUserName", rootElt.elementText("ToUserName"));
            wechatMsgData.put("FromUserName", rootElt.elementText("FromUserName"));
            wechatMsgData.put("CreateTime", rootElt.elementText("CreateTime"));
            wechatMsgData.put("MsgType", rootElt.elementText("MsgType"));
            wechatMsgData.put("MediaId", rootElt.elementText("MediaId"));
            wechatMsgData.put("Format", rootElt.elementText("Format"));
            wechatMsgData.put("Scale", rootElt.elementText("Scale"));
            wechatMsgData.put("MsgId", rootElt.elementText("MsgId"));
            wechatMsgData.put("Recognition", rootElt.elementText("Recognition"));

            String msgTxtContent = wechatMsgData.get("Recognition");
            Date msgTime = new Date(Long.parseLong(wechatMsgData.get("CreateTime")) * 1000);
            //0、text 1、语音 2、图片 3、位置
            Integer msgContentType = 1;
            //语音长度
            Integer radioLen = 0;
            String positionCoor = "";
            String positionName = "";
            //电台id 这里需要绑定公众号appid或者公众号原始id与电台id绑定
            Long rsId = wechatAccount.getRsId();

            //预创建目录
            String filePath = env.getProperty("media.dir") + "/audio/" + wechatAccount.getRsId() + "/" + wechatAccount.getAccountOriginalid();
            File dir = new File(filePath);
            if(!dir.exists() && !dir.isDirectory()){
                dir .mkdirs();
            }

            //下载语音
            String ACCESS_TOKEN = wechatAccount.getAccountAccesstoken();
            WxDwonload voiceFile = JwMediaAPI.downMedia(ACCESS_TOKEN, wechatMsgData.get("MediaId"), filePath);
            String newFilename = voiceFile.getFileName() + ((wechatMsgData.get("Format") != null) ? wechatMsgData.get("Format") : "");
            FileToolkit.renameFile(voiceFile.getFilepath() + "/" + voiceFile.getFileName(), newFilename);
            String msgAttachmentAddr = voiceFile.getFilepath() + "/" + newFilename;

            mp3ConvertorAndXfTransformService.handlerMsg(msgAttachmentAddr, rsId, wechatAccount.getAccountOriginalid(), new Mp3ConvertorAndXfTransformService.MsgCall() {
                @Override
                public void result(String convertedMp3Path, String xfTransformResult, String errMsg) {
                    try {
                        System.out.println("-------------xf:"+xfTransformResult);

                        logger.info("================语音地址=========="+localUrl+msgAttachmentAddr);
                        String audioPath = localUrl+msgAttachmentAddr ;
                        Integer audioTimeLength = AudioUtil.getAudioDuration(audioPath);
                        logger.info("================语音长度=========="+audioTimeLength);

                        // 如果前台无法播放那个amr 则使用convertedMp3Path 替换 msgAttachmentAddr 保存，。
                        saveMsg(wechatMsgData.get("ToUserName"), wechatMsgData.get("FromUserName"), wechatAccount, convertedMp3Path, wechatMsgData.get("Recognition"), msgTime, msgContentType, audioTimeLength, positionCoor, positionName, rsId, wechatMsgData);
                    } catch (WexinReqException e) {
                    }
                }
            });

        }
        //TODO Wmdz 有待继续扩展 其他消息类型的接收
    }

    private void saveMsg(String toUserName, String fromUserName, WechatAccount wechatAccount, String msgAttachmentAddr, String msgTxtContent, Date msgTime, Integer msgContentType, Integer radioLen, String positionCoor, String positionName, Long rsId, Map<String, String> wechatMsgData) throws WexinReqException {


        //https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
        String ACCESS_TOKEN = wechatAccount.getAccountAccesstoken();
        String OPENID = fromUserName;
        Wxuser wxuser = JwUserAPI.getWxuser(ACCESS_TOKEN, OPENID);
        logger.info(wxuser);
        /**
         {
         "country": "百慕大",
         "subscribe": 1,
         "city": "",
         "openid": "oEl-4uETCGjpmbYPmL1vwG7JOW4Q",
         "tagid_list": [],
         "sex": 1,
         "groupid": 0,
         "language": "zh_CN",
         "remark": "",
         "subscribe_time": 1397449973,
         "province": "",
         "nickname": "Winnid",
         "headimgurl": "http://wx.qlogo.cn/mmopen/PiajxSqBRaEI7F60cicOjHKdYAn2icukQDu74rNSP6ky8oebMxe954EEnLpZGia4tFpQjR4uQ2KClyVjZK1icwyBnzg/0"
         }
         */
        Map<String, String> wechatUserData = new HashMap<>();
        wechatUserData.put("country", wxuser.getCountry());
        wechatUserData.put("subscribe", wxuser.getSubscribe().toString());
        wechatUserData.put("city", wxuser.getCity());
        wechatUserData.put("openid", wxuser.getOpenid());
        wechatUserData.put("nickname", wxuser.getNickname());
        wechatUserData.put("tagid_list", StringUtils.join(wxuser.getTagid_list(), ","));
        wechatUserData.put("sex", wxuser.getSex());
        wechatUserData.put("groupid", wxuser.getGroupid().toString());
        wechatUserData.put("language", wxuser.getLanguage());
        wechatUserData.put("remark", wxuser.getRemark());
        wechatUserData.put("subscribe_time", wxuser.getSubscribe_time());
        wechatUserData.put("province", wxuser.getProvince());
        wechatUserData.put("headimgurl", wxuser.getHeadimgurl());
        wechatUserData.put("unionid", wxuser.getUnionid());

        Map<String, String> wechatIdData = new HashMap<>();
        wechatIdData.put("appid", wechatAccount.getAccountAppid());
        wechatIdData.put("originalid", toUserName);
        wechatIdData.put("openid", wxuser.getOpenid());
        wechatIdData.put("unionid", wxuser.getUnionid());

        //TODO wmdz 用户 不存在绑定了
        //用户id 这里需要绑定微信用户id和平台用户id
        Long userId = -1L;
        msgWebService.saveFromWechat(msgAttachmentAddr, msgTxtContent, msgTime, msgContentType, radioLen, positionCoor, positionName, rsId, userId, wechatIdData, wechatMsgData, wechatUserData);
    }

    public void replyEventMessage(HttpServletRequest request, HttpServletResponse response, String event, String toUserName, String fromUserName) throws DocumentException, IOException {
        String content = event + "from_callback";
        logger.info("---全网发布接入检测------step.4-------事件回复消息  content=" + content + "   toUserName=" + toUserName + "   fromUserName=" + fromUserName);
        //---全网发布接入检测------step.4-------事件回复消息  content=LOCATIONfrom_callback   toUserName=gh_3c884a361561   fromUserName=ozy4qt5QUADNXORxCVipKMV9dss0
        replyTextMessage(request, response, content, toUserName, fromUserName);
    }

    public void processTextMessage(HttpServletRequest request, HttpServletResponse response, String content, String toUserName, String fromUserName) throws IOException, DocumentException {
        logger.info("processTextMessage :" + content);
        //processTextMessage :QUERY_AUTH_CODE:queryauthcode@@@FRAb2PoTqAqmpm9qU8Z_CgLHhududFLz-soKXGCH1Rte8S3cg1q9lNI8iAuBmJk5enkwz3UflaWpeNexYxpv6w

        if (TESTCOMPONENT_MSG_TYPE_TEXT_STRING.equals(content)) {
            String returnContent = content + "_callback";
            replyTextMessage(request, response, returnContent, toUserName, fromUserName);
        } else if (StringUtils.startsWithIgnoreCase(content, QUERY_AUTH_CODE_STRING)) {
            output(response, "");
            //接下来客服API再回复一次消息
            replyApiTextMessage(request, response, content.split(":")[1], toUserName, fromUserName);
        }
    }

    /**
     * 回复微信服务器"文本消息"
     *
     * @param request
     * @param response
     * @param content
     * @param toUserName
     * @param fromUserName
     * @throws DocumentException
     * @throws IOException
     */
    public void replyTextMessage(HttpServletRequest request, HttpServletResponse response, String content, String toUserName, String fromUserName) throws DocumentException, IOException {
        WechatOpenAccount wechatOpenAccount = wechatOpenAccountService.load();
        WechatAccount wechatAccount = wechatAccountService.loadByOriginalid(toUserName);

        Long createTime = Calendar.getInstance().getTimeInMillis() / 1000;
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        sb.append("<ToUserName><![CDATA[" + fromUserName + "]]></ToUserName>");
        sb.append("<FromUserName><![CDATA[" + toUserName + "]]></FromUserName>");
        sb.append("<CreateTime>" + createTime + "</CreateTime>");
        sb.append("<MsgType><![CDATA[text]]></MsgType>");
        sb.append("<Content><![CDATA[" + content + "]]></Content>");
        sb.append("</xml>");
        String replyMsg = sb.toString();

        String returnvaleue = "";
        try {
            WXBizMsgCrypt pc = new WXBizMsgCrypt(wechatOpenAccount.getToken(), wechatOpenAccount.getEncodingAesKey(), wechatOpenAccount.getAppid());
            returnvaleue = pc.encryptMsg(replyMsg, createTime.toString(), "easemob");
            System.out.println("---------加密后的返回内容 returnvaleue： " + returnvaleue);
        } catch (AesException e) {
            e.printStackTrace();
        }
        output(response, returnvaleue);
    }

    public void replyApiTextMessage(HttpServletRequest request, HttpServletResponse response, String auth_code, String toUserName, String fromUserName) throws DocumentException, IOException {
        WechatOpenAccount wechatOpenAccount = wechatOpenAccountService.load();

        String authorizationCode = auth_code;
        // 得到微信授权成功的消息后，应该立刻进行处理！！相关信息只会在首次授权的时候推送过来
        System.out.println("------step.1----使用客服消息接口回复粉丝----逻辑开始---------");
        try {
            String componentAccessToken = wechatOpenAccountWebService.getComponentAccesstoken(wechatOpenAccount);

            System.out.println("------step.2----使用客服消息接口回复粉丝------- component_access_token = " + componentAccessToken + "---------authorization_code = " + authorizationCode);
            JSONObject authorizationInfoJson = JwThirdAPI.getApiQueryAuthInfo(wechatOpenAccount.getAppid(), authorizationCode, componentAccessToken);
            System.out.println("------step.3----使用客服消息接口回复粉丝--------- 获取authorizationInfoJson = " + authorizationInfoJson);
            JSONObject infoJson = authorizationInfoJson.getJSONObject("authorization_info");
            String authorizerAccessToken = infoJson.getString("authorizer_access_token");


            Map<String, Object> obj = new HashMap<String, Object>();
            Map<String, Object> msgMap = new HashMap<String, Object>();
            String msg = auth_code + "_from_api";
            msgMap.put("content", msg);

            obj.put("touser", fromUserName);
            obj.put("msgtype", "text");
            obj.put("text", msgMap);
            JwThirdAPI.sendMessage(obj, authorizerAccessToken);
        } catch (WexinReqException e) {
            e.printStackTrace();
        }

    }

    /**
     * 工具类：回复微信服务器"文本消息"
     *
     * @param response
     * @param returnvaleue
     */
    public void output(HttpServletResponse response, String returnvaleue) {
        try {
            PrintWriter pw = response.getWriter();
            pw.write(returnvaleue);
            System.out.println("**************** returnvaleue ***************=" + returnvaleue);
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 验证是否过期
     *
     * @param accessTokenExpires
     * @return
     */
    boolean isExpired(long accessTokenExpires) {
        return false;
    }

}